﻿using System;
using System.ServiceModel;
using System.Threading;
using VideoStore.Business.Facade;
using VideoStore.Common.Enum;
using VideoStore.Domain.Entities;
using Warehouse.Services.Base;
using Warehouse.Services.CustomerServiceReference;
using Warehouse.Services.Dto;
using Warehouse.Services.Factory;
using Warehouse.Services.Interface;
using Warehouse.Services.OrderServiceQueuedReference;
using Warehouse.Services.OrderServiceReference;
using Warehouse.Services.StockServiceReference;
using Warehouse.Services.Translation;
using OrderDto=Warehouse.Services.OrderServiceQueuedReference.OrderDto;
using OrderLinesDto=Warehouse.Services.OrderServiceQueuedReference.OrderLinesDto;

namespace Warehouse.Services
{
    public class DeliveryServiceQueued : IDeliveryServiceQueued
    {
        /// <summary>
        /// Submits the delivery.
        /// </summary>
        /// <param name="newDeliveryDto">The new delivery dto.</param>
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitDelivery(DeliveryDto newDeliveryDto)
        {
            try
            {
                Console.WriteLine("Got Delivery Id {0}", newDeliveryDto.Id);
                // We first create the delivery
                var facade = VideoStoreFacade.Instance;
                ITranslator translator = TranslatorFactory.GetTranslatorByType(typeof(DeliveryTranslator));
                var deliveryEntity = translator.TranslateToEntity<DeliveryDto, Delivery>(newDeliveryDto);
                Delivery savedEntity = facade.CreateDelivery(deliveryEntity);
                DeliveryDto deliveryDto = translator.TranslateToDto<Delivery, DeliveryDto>(savedEntity);
                // And then submit for processing
                var orderProxy = new OrderServiceClient();
                orderProxy.Open();
                var orderResponse = orderProxy.GetOrderById(deliveryDto.OrderId);
                orderProxy.Close();
                if (orderResponse.IsSuccessful)
                {
                    var stockProxy = new StockServiceClient();
                    stockProxy.Open();
                    var orderDto = orderResponse.ResponseObject;
                    foreach (var video in orderDto.OrderLinesDto)
                    {
                        var stockResponse = stockProxy.Sold(video.CatalogueId, video.Quantity, orderDto.WarehouseId);
                        if (stockResponse.IsSuccessful)
                        {
                            int holding = stockResponse.ResponseObject;
                            if (holding <= 10)
                            {
                                // here we could do the auto ordering as the holding quantity is 
                                // less than the threshold ... 
                            }
                        }
                    }
                    stockProxy.Close();
                    var customerProxy = new CustomerServiceClient();
                    customerProxy.Open();
                    var customerResponse = customerProxy.GetCustomerById(orderDto.CustomerId);
                    if (customerResponse.IsSuccessful)
                    {
                        var customerDto = customerResponse.ResponseObject;
                        Console.WriteLine("Delivering Order Id {0} for Customer Name {1}", orderDto.Id,
                                            customerDto.Name);
                        foreach (var video in orderDto.OrderLinesDto)
                        {
                            Console.WriteLine("  {0} of video {1} from {2} warehouse\n", video.Quantity,
                                                video.CatalogueId, orderDto.WarehouseId);
                        }
                        customerProxy.Close();
                    }
                    Console.WriteLine("Sending request for updating Order status to {0}", OrderStatus.Delivered);
                    var orderQueuedProxy = new OrderServiceQueuedClient();
                    orderQueuedProxy.Open();
                    var modifiedOrderDto = new OrderDto();
                    modifiedOrderDto.Id = orderDto.Id;
                    modifiedOrderDto.CustomerId = orderDto.CustomerId;
                    modifiedOrderDto.OrderDate = orderDto.OrderDate;
                    modifiedOrderDto.OrderStatus = OrderStatus.Delivered;
                    Console.WriteLine("Simulating network latency ... thread sleeps for 10 secs");
                    Thread.Sleep(10000);
                    orderQueuedProxy.UpdateOrderStatus(modifiedOrderDto);
                    orderQueuedProxy.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
